#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "satellitepos.h"
#include "coordgeodetic.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QThread>
#include <QTextCodec>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)

{    // 初始化
    ui->setupUi(this);
    ui->progressBar->setRange(0, 100);
    qRegisterMetaType<AnalysisParams>();
    // qRegisterMetaType<libsgp4::CoordGeodetic>();
    initStyleSheets(); // 添加样式初始化调用
    setupConnections();
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));//强制设置全局编码格式为UTF8
    // 新增：根据TLE源切换控件状态
    connect(ui->rbLocalTle, &QRadioButton::toggled, ui->leTlePath, &QWidget::setEnabled);
    connect(ui->rbLocalTle, &QRadioButton::toggled, ui->btnTleBrowse, &QWidget::setEnabled);
    // 初始状态设置
    ui->leTlePath->setEnabled(ui->rbLocalTle->isChecked());
    ui->btnTleBrowse->setEnabled(ui->rbLocalTle->isChecked());
}

void MainWindow::setupConnections() {
    connect(ui->btnNoradBrowse, &QPushButton::clicked, this, &MainWindow::onBrowseNorad);
    connect(ui->btnTleBrowse, &QPushButton::clicked, this, &MainWindow::onBrowseTle);
    connect(ui->btnEvents, &QPushButton::clicked, this, &MainWindow::onBrowseEvents);
    connect(ui->btnSetParams, &QPushButton::clicked, this, &MainWindow::onStartAnalysis);
    // 连接卫星位置计算器信号
    connect(&m_satPos, &SatellitePos::progressUpdated, ui->progressBar, &QProgressBar::setValue);
    connect(&m_satPos, &SatellitePos::errorOccurred, this, &MainWindow::handleError);
    connect(&m_satPos, &SatellitePos::dataReady, this, &MainWindow::handleDataReady);
}



void MainWindow::initStyleSheets() {
    // 设置按钮样式
    QString btnStyle = "QPushButton { background: #4CAF50; color: white; border-radius: 4px; }"
                       "QPushButton:hover { background: #45a049; }";
    ui->btnNoradBrowse->setStyleSheet(btnStyle);
    ui->btnTleBrowse->setStyleSheet(btnStyle);
    ui->btnEvents->setStyleSheet(btnStyle);
    ui->btnSetParams->setStyleSheet(btnStyle);

    // 设置输入框样式
    QString lineEditStyle = "QLineEdit { border: 1px solid #ccc; padding: 5px; }";
    ui->leNoradPath->setStyleSheet(lineEditStyle);
    ui->leTlePath->setStyleSheet(lineEditStyle);
    ui->leEventsPath->setStyleSheet(lineEditStyle);
}

// 文件浏览槽函数

void MainWindow::onBrowseNorad() {
    // 允许选择目录
    QString path = QFileDialog::getExistingDirectory(
        this,
        "选择卫星NORAD目录",
        "",
        QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
        );
    if (!path.isEmpty()) {
        ui->leNoradPath->setText(path);
    }
}


void MainWindow::onBrowseTle() {
    // 允许选择目录
    QString path = QFileDialog::getExistingDirectory(
        this,
        "选择TLE目录",
        "",
        QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
        );
    if (!path.isEmpty()) {
        ui->leTlePath->setText(path);
    }
}


void MainWindow::onBrowseEvents() {
    QString path = QFileDialog::getOpenFileName(
        this,
        "选择事件文件",
        "",
        "CSV文件 (*.csv);;所有文件 (*.*)"
        );
    if (!path.isEmpty()) {
        ui->leEventsPath->setText(path);
    }
}

// 启动分析核心逻辑
void MainWindow::onStartAnalysis() {
    // 获取TLE来源模式
    SatellitePos::TleSource tleSource = ui->rbLocalTle->isChecked()
                                            ? SatellitePos::LocalFiles
                                            : SatellitePos::OnlineSource;
    // 获取事件文件路径（从UI控件）
    QString eventsPath = ui->leEventsPath->text();
    // 参数验证增强
    if (ui->leNoradPath->text().isEmpty()) {
        QMessageBox::warning(this, "错误", "必须选择NORAD文件路径");
        ui->leNoradPath->setFocus();
        return;
    }

    if (ui->rbLocalTle->isChecked() && ui->leTlePath->text().isEmpty()) {
        QMessageBox::warning(this, "错误", "本地模式必须选择TLE目录");
        ui->leTlePath->setFocus();
        return;
    }

    // 禁用按钮防止重复点击
    ui->btnSetParams->setEnabled(false);
    qApp->processEvents(); // 立即更新界面


    // 获取观测站坐标
    libsgp4::CoordGeodetic obsGeo(
        ui->LA->value(),//这里是不需要自己加弧度转换的！程序自己会转换（因为默认是角度输入，弧度计算，有内置转换），加了则重复转换了
        ui->LO->value(),
        ui->AL->value() / 1000.0,   //高度单位转换为千米
        false                    // 指明传入的是度数，需内部转弧度
        //ui->AL->value()
        );

    // 坐标验证
    if (qAbs(ui->LO->value()) > 180.0 || qAbs(ui->LA->value()) > 90.0) {
        QMessageBox::critical(this, "错误", "经度范围[-180,180] 纬度范围[-90,90]");
        return;
    }
    qDebug() << "观测站原始输入值:"
             << "\n经度 (deg):" << ui->LO->value()
             << "\n纬度 (deg):" << ui->LA->value()
             << "\n高度 (m):" << ui->AL->value();
    qDebug() << "观测站坐标 (弧度):"
             << "\n经度:" << obsGeo.longitude
             << "\n纬度:" << obsGeo.latitude
             << "\n高度:" << obsGeo.altitude;

    // 获取最小仰角和时间步长
    double minElev = ui->dsbMinElev->value();
    int timeStep = ui->sbTimeStep->value();

    // 创建分析线程,加速计算
    m_analysisThread = new QThread();
    m_analyzer = new EventAnalyzer(nullptr, obsGeo,
                                   QFileInfo(ui->leEventsPath->text()).path(),
                                   minElev, timeStep);
    // 添加自动清理连接
    connect(m_analysisThread, &QThread::finished,
            m_analyzer, &QObject::deleteLater);
    connect(m_analysisThread, &QThread::finished,
            m_analysisThread, &QObject::deleteLater);

    // // 错误处理连接
    // connect(m_analyzer, &EventAnalyzer::errorOccurred, this, [this](const QString& err){
    //     QMessageBox::critical(this, "错误", err);
    // });

    // 设置分析参数
    QDateTime startTime = QDateTime::currentDateTime();
    QDateTime endTime = startTime.addSecs(3600); // 1小时
    m_analyzer->setAnalysisParams(
        // QDateTime::currentDateTime(),
        // QDateTime::currentDateTime().addDays(1),
        startTime,   // 开始时间
        endTime,     // 结束时间（明确传递有效值）
        ui->leNoradPath->text(),
        ui->leTlePath->text(),
        ui->leEventsPath->text(),      // 传入CSV路径
        tleSource,                // 新增参数
        ui->cbAllNorad->isChecked() // 全选状态
        );

    m_analyzer->setEventsPath(eventsPath); // 新增方法

    // 连接信号
    connect(m_analyzer, &EventAnalyzer::progressUpdated, this, &MainWindow::updateProgress);
    connect(m_analyzer, &EventAnalyzer::progressUpdated, ui->progressBar, &QProgressBar::setValue);
    connect(m_analyzer, &EventAnalyzer::analysisFinished, this, [this](bool success) {
        if(m_analysisThread){
        m_analysisThread->quit();
        m_analysisThread->wait(2000);  // 等待线程结束
        delete m_analysisThread;   // 释放线程
        m_analysisThread = nullptr;
        }
        QMessageBox::information(this, "完成", success ? "分析完成！！！" : "分析失败！！！QAQ");
        ui->btnSetParams->setEnabled(true);  // 重新启用按钮
    });

    // 启动线程
    m_analyzer->moveToThread(m_analysisThread);
    connect(m_analysisThread, &QThread::started,
            m_analyzer, [this](){
                QMetaObject::invokeMethod(m_analyzer, "startAnalysis", Qt::QueuedConnection);
            });// 改用信号槽触发异步操作
    m_analysisThread->start();
    connect(m_analyzer, &EventAnalyzer::analysisFinished, ui->btnSetParams, &QPushButton::setEnabled);
}

void MainWindow::updateProgress(int percent) {
    ui->progressBar->setValue(percent); // 更新进度条
}

// void MainWindow::handleProgress(int percent)
// {
//     // 统一进度处理逻辑
//     ui->progressBar->setValue(percent);
//     ui->statusBar->showMessage(QString("进度: %1%").arg(percent));
// }

void MainWindow::handleDataReady()
{
    QMessageBox::information(this, "完成", "TLE数据加载完成");
    ui->btnSetParams->setEnabled(true); // 启用分析按钮
}

void MainWindow::handleError(const QString& errorMsg)
{
    QMessageBox::critical(this, "错误", errorMsg);
    ui->btnSetParams->setEnabled(true); // 恢复按钮状态
}

MainWindow::~MainWindow() {
    delete ui;
    // 安全停止线程
    if (m_analysisThread && m_analysisThread->isRunning()) {
        m_analysisThread->requestInterruption();
        m_analysisThread->quit();
        m_analysisThread->wait(1000);
    }
}
